'use client'

import React from 'react'
import { useState, useEffect, useCallback } from 'react'
import { Card } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { DatePickerWithRange } from '@/components/DatePickerWithRange'
import { PieChart, Pie, Cell, ResponsiveContainer, Tooltip, Legend } from 'recharts'
import { ArrowDown, ArrowUp, Download } from 'lucide-react'
import { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs'
import type { DateRange } from 'react-day-picker'
import * as XLSX from 'xlsx'
import { toast } from 'sonner'
import { format } from 'date-fns'
import { Table, TableCell, TableRow } from '@/components/ui/table'

type TimeRange = 'today' | 'week' | 'month' | 'custom'
type ViewType = 'chart' | 'table'

interface MetricCard {
  title: string
  value: number
  change?: {
    day: number
    week: number
  }
}

const TIME_RANGES = [
  { value: 'today', label: '本日' },
  { value: 'week', label: '本周' },
  { value: 'month', label: '本月' },
  { value: 'custom', label: '自定义' },
]

const COLORS = ['#1677FF', '#52C41A', '#722ED1', '#F5222D', '#FA8C16']

// 格式化数字
const formatNumber = (num: number) => {
  return new Intl.NumberFormat('zh-CN').format(num)
}

// 格式化百分比
const formatPercent = (num: number | string | null | undefined) => {
  if (num === undefined || num === null) return null
  const value = typeof num === 'string' ? parseFloat(num) : num
  if (isNaN(value)) return null
  return `${value > 0 ? '+' : ''}${value.toFixed(2)}%`
}

// 渲染增长率的组件
const GrowthRate = React.memo(({ 
  value, 
  label,
  showPlaceholder = true 
}: { 
  value: number | string | null | undefined
  label: string
  showPlaceholder?: boolean
}) => {
  const formattedValue = formatPercent(value)
  const numericValue = value ? (typeof value === 'string' ? parseFloat(value) : value) : 0
  
  if (!formattedValue && !showPlaceholder) return null
  
  return (
    <div className="flex items-center text-sm">
      <span className="text-gray-500 mr-2">{label}</span>
      {formattedValue ? (
        <span className={`flex items-center ${numericValue > 0 ? 'text-green-500' : 'text-red-500'}`}>
          {numericValue > 0 ? <ArrowUp className="w-3 h-3 mr-1" /> : <ArrowDown className="w-3 h-3 mr-1" />}
          {formattedValue}
        </span>
      ) : (
        <span className="text-gray-400">--</span>
      )}
    </div>
  )
})

GrowthRate.displayName = 'GrowthRate'

// 自定义工具提示组件
const CustomTooltip = React.memo(({ active, payload }: any) => {
  if (active && payload && payload.length) {
    const data = payload[0]
    const total = data.payload.value + (data.payload.otherValue || 0)
    const percent = ((data.value / total) * 100).toFixed(2)
    
    return (
      <div className="bg-white p-3 shadow-lg rounded-lg border">
        <p className="font-medium">{data.name}</p>
        <p className="text-sm">
          数量: {formatNumber(data.value)}
        </p>
        <p className="text-sm">
          占比: {percent}%
        </p>
      </div>
    )
  }
  return null
})

CustomTooltip.displayName = 'CustomTooltip'

// 指标卡片组件
const MetricCard = React.memo(({ metric, isLoading }: { metric: MetricCard, isLoading: boolean }) => (
  <Card className="p-6 shadow-sm hover:shadow-md transition-shadow duration-200">
    <div className="space-y-3">
      <div className="text-sm font-medium text-gray-600">{metric.title}</div>
      <div className="text-2xl font-bold text-gray-900">
        {isLoading ? (
          <span className="text-gray-300">--</span>
        ) : (
          <>{formatNumber(metric.value)}{metric.title.includes('时长') && ' 秒'}</>
        )}
      </div>
      {metric.change && !isLoading && (
        <div className="space-y-2 pt-3 border-t border-gray-100">
          <GrowthRate value={metric.change.day} label="较昨日" />
          <GrowthRate value={metric.change.week} label="较上周同期" />
        </div>
      )}
    </div>
  </Card>
))

MetricCard.displayName = 'MetricCard'

export default function VideoAnalysisPage() {
  const [timeRange, setTimeRange] = useState<TimeRange>('today')
  const [viewType, setViewType] = useState<ViewType>('chart')
  const [dateRange, setDateRange] = useState<DateRange>({
    from: new Date(),
    to: new Date()
  })
  const [timeDescription, setTimeDescription] = useState<string>('')
  const [metrics, setMetrics] = useState<MetricCard[]>([])
  const [imageData, setImageData] = useState<Array<{ name: string; value: number }>>([])
  const [failureData, setFailureData] = useState<Array<{ name: string; value: number }>>([])
  const [error, setError] = useState<string | null>(null)
  const [isLoading, setIsLoading] = useState(false)
  const [overviewData, setOverviewData] = useState<any>(null)

  // 获取日期参数
  const getDateParams = useCallback(() => {
    const now = new Date()
    const today = format(now, 'yyyy-MM-dd')
    let startDate: string
    let endDate: string

    switch (timeRange) {
      case 'today':
        startDate = today
        endDate = today
        break
      case 'week':
        const weekStart = new Date(now)
        weekStart.setDate(now.getDate() - 6)
        startDate = format(weekStart, 'yyyy-MM-dd')
        endDate = today
        break
      case 'month':
        const monthStart = new Date(now.getFullYear(), now.getMonth(), 1)
        startDate = format(monthStart, 'yyyy-MM-dd')
        endDate = today
        break
      case 'custom':
        if (!dateRange?.from || !dateRange?.to) {
          throw new Error('请选择日期范围')
        }
        if (dateRange.from > dateRange.to) {
          throw new Error('开始日期不能晚于结束日期')
        }
        startDate = format(dateRange.from, 'yyyy-MM-dd')
        endDate = format(dateRange.to, 'yyyy-MM-dd')
        break
      default:
        startDate = today
        endDate = today
    }

    return { startDate, endDate }
  }, [timeRange, dateRange])

  // 更新时间描述
  const updateTimeDescription = useCallback(() => {
    const today = new Date()
    let description = ''

    switch (timeRange) {
      case 'today':
        description = `${today.getFullYear()}年${today.getMonth() + 1}月${today.getDate()}日`
        break
      case 'week':
        const weekStart = new Date(today)
        weekStart.setDate(today.getDate() - 6)
        description = `${weekStart.getMonth() + 1}月${weekStart.getDate()}日 至 ${today.getMonth() + 1}月${today.getDate()}日`
        break
      case 'month':
        description = `${today.getFullYear()}年${today.getMonth() + 1}月1日 至 ${today.getMonth() + 1}月${today.getDate()}日`
        break
      case 'custom':
        if (dateRange?.from && dateRange?.to) {
          const fromDate = dateRange.from.toLocaleDateString('zh-CN', { year: 'numeric', month: 'long', day: 'numeric' })
          const toDate = dateRange.to.toLocaleDateString('zh-CN', { year: 'numeric', month: 'long', day: 'numeric' })
          description = `${fromDate} 至 ${toDate}`
        }
        break
    }

    setTimeDescription(description)
  }, [timeRange, dateRange])

  const fetchData = useCallback(async () => {
    if (isLoading) return

    try {
      setIsLoading(true)
      setError(null)

      const { startDate, endDate } = getDateParams()

      // 构建请求参数
      const params = new URLSearchParams({
        startDate,
        endDate,
        timeRange
      })

      // 并行请求三个接口
      const [overviewRes, detailsRes, failuresRes] = await Promise.all([
        fetch(`/api/video-analysis/overview?${params}`),
        fetch(`/api/video-analysis/details?${params}`),
        fetch(`/api/video-analysis/failures?${params}`)
      ])

      if (!overviewRes.ok || !detailsRes.ok || !failuresRes.ok) {
        throw new Error('API request failed')
      }

      const [overviewResponse, detailsResponse, failuresResponse] = await Promise.all([
        overviewRes.json(),
        detailsRes.json(),
        failuresRes.json()
      ])

      if (!overviewResponse.success || !detailsResponse.success || !failuresResponse.success) {
        throw new Error(overviewResponse.message || detailsResponse.message || failuresResponse.message || 'API response indicates failure')
      }

      const overviewData = overviewResponse.data

      // 转换总览数据
      const metricsData: MetricCard[] = [
        {
          title: '视频生成总数',
          value: overviewData.totalVideoCount.value || 0,
          change: {
            day: overviewData.totalVideoCount.dayOnDay || 0,
            week: overviewData.totalVideoCount.weekOnWeek || 0
          }
        },
        {
          title: '视频生成用户数',
          value: overviewData.totalUserCount.value || 0,
          change: {
            day: overviewData.totalUserCount.dayOnDay || 0,
            week: overviewData.totalUserCount.weekOnWeek || 0
          }
        },
        {
          title: '平均每次视频时长',
          value: overviewData.avgProcessTime.value || 0,
          change: {
            day: overviewData.avgProcessTime.dayOnDay || 0,
            week: overviewData.avgProcessTime.weekOnWeek || 0
          }
        },
        {
          title: '视频失败总次数',
          value: overviewData.totalFailCount.value || 0,
          change: {
            day: overviewData.totalFailCount.dayOnDay || 0,
            week: overviewData.totalFailCount.weekOnWeek || 0
          }
        }
      ]

      // 批量更新状态
      setMetrics(metricsData)
      setImageData(Array.isArray(detailsResponse.data) ? detailsResponse.data : [])
      setFailureData(Array.isArray(failuresResponse.data) ? failuresResponse.data : [])
      setOverviewData(overviewData)

    } catch (error) {
      console.error('Error fetching data:', error)
      setError(error instanceof Error ? error.message : '获取数据失败')
      setMetrics([])
      setImageData([])
      setFailureData([])
      setOverviewData(null)
    } finally {
      setIsLoading(false)
    }
  }, [timeRange, getDateParams])

  // 初始化
  useEffect(() => {
    updateTimeDescription()
    fetchData()
  }, [updateTimeDescription, fetchData])

  // 处理时间范围变化
  const handleTimeRangeChange = useCallback((newTimeRange: TimeRange) => {
    setTimeRange(newTimeRange)
  }, [])

  // 处理日期范围变化
  const handleDateRangeChange = useCallback((range: DateRange | undefined) => {
    if (range?.from && range?.to) {
      setDateRange(range)
    }
  }, [])

  // 监听时间范围和日期范围变化
  useEffect(() => {
    updateTimeDescription()
    fetchData()
  }, [timeRange, dateRange, updateTimeDescription, fetchData])

  // 优化图表渲染
  const renderPieChart = useCallback((data: Array<{ name: string; value: number }>, title: string) => (
    <Card className="p-6">
      <div className="space-y-4">
        <h4 className="text-base font-medium">{title}</h4>
        <div className="h-[400px]">
          {isLoading ? (
            <div className="flex items-center justify-center h-full">
              <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900"></div>
            </div>
          ) : (
            <ResponsiveContainer width="100%" height="100%">
              <PieChart>
                <Pie
                  data={data}
                  dataKey="value"
                  nameKey="name"
                  cx="50%"
                  cy="50%"
                  outerRadius={120}
                  label={({ name, percent }) => `${name}: ${(percent * 100).toFixed(2)}%`}
                >
                  {data.map((_, index) => (
                    <Cell key={`cell-${index}`} fill={COLORS[index % COLORS.length]} />
                  ))}
                </Pie>
                <Tooltip content={<CustomTooltip />} />
                <Legend />
              </PieChart>
            </ResponsiveContainer>
          )}
        </div>
      </div>
    </Card>
  ), [isLoading])

  // 修改表格数据处理逻辑
  const getTableData = () => {
    if (!imageData || !failureData || !overviewData) return []

    // 计算总量
    const totalImageCount = imageData.reduce((sum, item) => sum + (item.value || 0), 0)
    const totalFailCount = failureData.reduce((sum, item) => sum + (item.value || 0), 0)
    
    // 使用 overviewData 中的数据
    return [{
      date: timeDescription,
      type: '视频生成',
      imageCount: overviewData.totalVideoCount.value || 0,
      userCount: overviewData.totalUserCount.value || 0,
      avgProcessTime: Number(overviewData.avgProcessTime.value || 0).toFixed(2),
      failCount: overviewData.totalFailCount.value || 0
    }]
  }

  // 修改下载逻辑
  const handleDownload = () => {
    let startDate, endDate;
    const now = new Date();
    const today = format(now, 'yyyy-MM-dd');

    switch (timeRange) {
      case 'today':
        startDate = today;
        endDate = today;
        break;
      case 'week':
        const weekStart = new Date(now);
        weekStart.setDate(now.getDate() - 6);
        startDate = format(weekStart, 'yyyy-MM-dd');
        endDate = today;
        break;
      case 'month':
        const monthStart = new Date(now.getFullYear(), now.getMonth(), 1);
        startDate = format(monthStart, 'yyyy-MM-dd');
        endDate = today;
        break;
      case 'custom':
        if (!dateRange?.from || !dateRange?.to) {
          toast.error('请选择日期范围');
          return;
        }
        if (dateRange.from > dateRange.to) {
          toast.error('开始日期不能晚于结束日期');
          return;
        }
        startDate = format(dateRange.from, 'yyyy-MM-dd');
        endDate = format(dateRange.to, 'yyyy-MM-dd');
        break;
      default:
        startDate = today;
        endDate = today;
    }

    const params = new URLSearchParams({
      startDate,
      endDate,
      timeRange
    }).toString();

    // 使用导出专用的API
    const downloadUrl = `/api/video-analysis/export?${params}`;
    
    // 获取详细数据并生成Excel
    fetch(downloadUrl)
      .then(response => {
        if (!response.ok) {
          throw new Error('导出请求失败');
        }
        return response.json();
      })
      .then(data => {
        if (!data.success) {
          throw new Error(data.message || '导出失败');
        }

        // 准备导出数据
        const exportData = data.data.map((item: any) => ({
          '日期': item.date,
          '类型': '视频生成',
          '生成总数': item.imageCount,
          '用户总数': item.userCount,
          '平均时长(秒)': Number(item.avgProcessTime).toFixed(2),
          '失败总数': item.failCount
        }));

        // 创建工作簿
        const wb = XLSX.utils.book_new();
        const ws = XLSX.utils.json_to_sheet(exportData);

        // 设置列宽
        const columnWidths = [
          { wch: 15 }, // 日期
          { wch: 10 }, // 类型
          { wch: 12 }, // 生成总数
          { wch: 12 }, // 用户总数
          { wch: 15 }, // 平均时长
          { wch: 12 }, // 失败总数
        ];
        ws['!cols'] = columnWidths;

        XLSX.utils.book_append_sheet(wb, ws, '视频分析数据');

        // 根据时间范围生成文件名
        let filename;
        switch (timeRange) {
          case 'today':
            filename = `视频分析数据_${today}`;
            break;
          case 'week':
            filename = `视频分析数据_本周_${startDate}_${endDate}`;
            break;
          case 'month':
            filename = `视频分析数据_本月_${startDate}_${endDate}`;
            break;
          case 'custom':
            filename = `视频分析数据_${startDate}_${endDate}`;
            break;
          default:
            filename = `视频分析数据_${today}`;
        }

        // 下载文件
        XLSX.writeFile(wb, `${filename}.xlsx`);
      })
      .catch(error => {
        console.error('Export error:', error);
        toast.error(error.message || '导出失败');
      });
  }

  if (error) {
    return (
      <div className="p-6">
        <div className="text-red-500 text-center">{error}</div>
      </div>
    )
  }

  return (
    <div className="space-y-6 px-4 pt-4">
      <div className="flex items-center justify-between">
        <h3 className="text-xl font-semibold">视频分析</h3>
        <Tabs value={viewType} onValueChange={(value) => setViewType(value as ViewType)}>
          <TabsList>
            <TabsTrigger value="chart">图表</TabsTrigger>
            <TabsTrigger value="table">表格</TabsTrigger>
          </TabsList>
        </Tabs>
      </div>

      {/* 筛选条件 */}
      <Card className="p-6 shadow-lg">
        <div className="space-y-4">
          <div className="flex items-center justify-between">
            <div className="flex items-center gap-4">
              <div className="flex items-center gap-2">
                {TIME_RANGES.map(range => (
                  <Button
                    key={range.value}
                    variant={timeRange === range.value ? "default" : "outline"}
                    onClick={() => handleTimeRangeChange(range.value as TimeRange)}
                    className="shadow-sm hover:shadow-md transition-all duration-200"
                  >
                    {range.label}
                  </Button>
                ))}
              </div>
              {timeRange === 'custom' && (
                <div className="relative">
                  <DatePickerWithRange
                    value={{
                      from: dateRange.from,
                      to: dateRange.to
                    }}
                    onChange={handleDateRangeChange}
                  />
                </div>
              )}
            </div>
          </div>
          {/* 时间范围显示 */}
          <div className="flex items-center pt-4 border-t border-gray-100">
            <div className="text-sm text-gray-500">
              当前数据范围：
              <span className="ml-2 text-gray-900 font-medium">{timeDescription}</span>
            </div>
          </div>
        </div>
      </Card>

      {/* 指标总览 */}
      <div className="grid grid-cols-4 gap-6">
        {metrics.map((metric, index) => (
          <MetricCard key={index} metric={metric} isLoading={isLoading} />
        ))}
      </div>

      {viewType === 'chart' ? (
        <div className="grid grid-cols-2 gap-6">
          {renderPieChart(imageData, '图片上传数量占比')}
          {renderPieChart(failureData, '视频失败原因占比')}
        </div>
      ) : (
        <Card className="p-6">
          <div className="space-y-4">
            <div className="flex justify-end">
              <Button
                variant="outline"
                size="sm"
                onClick={handleDownload}
                className="flex items-center gap-2"
              >
                <Download className="w-4 h-4" />
                导出数据
              </Button>
            </div>
            <div className="border rounded-lg">
              <table className="w-full">
                <thead>
                  <tr className="border-b bg-gray-50">
                    <th className="text-left p-4">日期</th>
                    <th className="text-left p-4">类型</th>
                    <th className="text-right p-4">生成总数</th>
                    <th className="text-right p-4">用户总数</th>
                    <th className="text-right p-4">平均时长(秒)</th>
                    <th className="text-right p-4">失败总数</th>
                  </tr>
                </thead>
                <tbody>
                  {isLoading ? (
                    <tr>
                      <td colSpan={6} className="text-center py-4">
                        <div className="flex items-center justify-center">
                          <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900"></div>
                        </div>
                      </td>
                    </tr>
                  ) : getTableData().map((row, index) => (
                    <TableRow key={index}>
                      <TableCell>{row.date}</TableCell>
                      <TableCell>{row.type}</TableCell>
                      <TableCell className="text-right">{formatNumber(row.imageCount)}</TableCell>
                      <TableCell className="text-right">{formatNumber(row.userCount)}</TableCell>
                      <TableCell className="text-right">
                        {typeof row.avgProcessTime === 'number' ? 
                          Number(row.avgProcessTime).toFixed(2) : 
                          (row.avgProcessTime || '0.00')}
                      </TableCell>
                      <TableCell className="text-right">{formatNumber(row.failCount)}</TableCell>
                    </TableRow>
                  ))}
                </tbody>
              </table>
            </div>
          </div>
        </Card>
      )}
    </div>
  )
} 